package com.ruoyi.web.controller.system;

import java.util.Date;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.druid.sql.visitor.functions.Char;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;

/**
 * 首页 业务处理
 * 
 * @author ruoyi
 */
@Controller
public class GrantxxxController extends BaseController
{
    /**
     * 是否开启记住我功能
     */
    @Value("${shiro.rememberMe.enabled: false}")
    private boolean rememberMe;

    // 系统首页
    @GetMapping("/grantxxx/{code}")
    public String index1(@PathVariable String code, ModelMap mmap)
    {
        // 取身份信息
        SysUser user = getSysUser();
        if (user != null) {        	
        	mmap.put("user", user);
        }
        mmap.put("code", code);
        // 是否开启记住我
        mmap.put("isRemembered", rememberMe);
        return "grantxxx";
    }
    
    @RequiresPermissions("system:grantxxx")
    @Log(title = "测试标题", businessType = BusinessType.GRANT, isSaveRequestData = true, isSaveResponseData = true)
    @PostMapping("/grantxxx")
    @ResponseBody
    public AjaxResult ajaxGrantxxx(String code, String grantLimit, Boolean rememberMe)
    {
        try
        {	
        	Date date = new Date();
        	Date limitDate = null; 
        	
        	if ("1m".equalsIgnoreCase(grantLimit)) {
        		limitDate = DateUtils.addMonths(date, 1);
        	}
        	if ("6m".equalsIgnoreCase(grantLimit)) {
        		limitDate = DateUtils.addMonths(date, 6);
        	}
        	if ("1y".equalsIgnoreCase(grantLimit)) {
        		limitDate = DateUtils.addYears(date, 1);
        	}
        	if ("fe".equalsIgnoreCase(grantLimit)) {
        		limitDate = DateUtils.parseDate("2099-12-31");
        	}
        	
        	if (limitDate == null) {
        		throw new RuntimeException("授权期限异常");
        	}
        	
        	String limitDayStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, limitDate);
        	
        	int limitDay = Integer.parseInt(DateUtils.parseDateToStr("yyMMdd", limitDate));
        	
        	String grantCode = encode(code, limitDay);
            return success().put("grantCode", grantCode).put("grantLimit", limitDayStr);
        }
        catch (Exception e)
        {
            String msg = "授权发生错误";
            if (StringUtils.isNotEmpty(e.getMessage()))
            {
                msg = e.getMessage();
            }
            return error(msg);
        }
    }
    
    private static String encode(String sourceCode, int limitDay) {
    	String sourceCodeSignStr = getSign(sourceCode);
    	
    	String limitDay16 = Integer.toHexString(limitDay);
    	
    	String grantCode = sourceCodeSignStr + limitDay16;
    	
    	return getSign(grantCode) + grantCode;
    }
    
    private static int decode(String sourceCode, String grantCode) {
    	// 1. 整体验签
    	if (!grantCode.substring(0, 2).equals(getSign(grantCode.substring(2)))) {
    		throw new RuntimeException("整体验签失败, 授权码被篡改");
    	}
    	
    	// 2. 局部验签
    	if (!grantCode.substring(2, 4).equals(getSign(sourceCode))) {
    		throw new RuntimeException("局部验签失败, 该该授权码不是针对该序列号的授权码");
    	}
    	
    	String subStr = grantCode.substring(4);
    	return Integer.parseInt(subStr, 16);
    }
    
    // 签名算法
    private static String getSign(String sourceCode) {
    	if (StringUtils.isBlank(sourceCode)) {
    		return sourceCode;
    	}
    	
    	char[] chars = sourceCode.toCharArray();
    	
    	int sign = 0;
    	for (char c : chars) {
			sign += Integer.valueOf(c);
		}
    	
    	System.out.println("sign is: " + sign);
    	
    	String signHex = "00" + Integer.toHexString(sign);
    	System.out.println("signHex is: " + signHex);
    	
    	return signHex.substring(signHex.length() - 2);
    }
    
    public static void main(String[] args) {
    	int num = 240615;
//    	System.out.println(num + " 的二进制是:" + Integer.toBinaryString(num));
//    	System.out.println(num + " 的八进制是:" + Integer.toOctalString(num));
    	System.out.println(num + " 的十六进制是:" + Integer.toHexString(num));
//    	System.out.println(num + " 的25进制是:" + Integer.toString(num, 25));
    	
//    	System.out.println(num + " 的25进制解密:" + Integer.parseInt(Integer.toString(num, 25), 25));
    	
    	String sourceCode = "ff4c36572ecdf53511d0d2c3977857e835ddf2ae";
    	String grantCode = encode(sourceCode, num);
    	System.out.println(grantCode);
    	System.out.println(decode(sourceCode, grantCode));
    }
}
